// 引入所有的组件
import Food from './food'
import LevelScore from './levelScore'
import Snake from './snake'

class GameControl{
    snake:Snake
    food:Food
    levelScore:LevelScore
    // 存储蛇的移动方向
    direction:string = "Right" 
    // 标志蛇是否还活着
    isLive = true


    constructor(){
        this.food = new Food()
        this.snake = new Snake()
        this.levelScore = new LevelScore()

        this.init()
    }
    // 游戏初始化
    init(){
        // 监听上下键
        document.addEventListener('keydown',this.keydownHandler.bind(this))
        // 蛇跟随上下键动
        this.run()
    }
    // 监听键盘，以Arrow开头的是谷歌的，另一种是IE的；不是上下键，就不改变方向，如果不写判断，不是上下键就会停止不动
    keydownHandler(event:KeyboardEvent){
        // if(event.key === 'ArrowUp' ||
        //  event.key === 'Up' || 
        //  event.key === 'ArrowDown' || 
        //  event.key === 'Down' || 
        //  event.key === 'ArrowLeft' || 
        //  event.key === 'Left' || 
        //  event.key === 'ArrowRight' || 
        //  event.key === 'Right'){
        //     this.direction = event.key
        // }

        let arr = ['ArrowUp','Up','ArrowDown','Down','ArrowLeft','Left','ArrowRight','Right']
        let flag = arr.some(( item ) => { 
            return item === event.key; 
        })
        if(flag){
            this.direction = event.key
        }
    }

    run(){
        // 获取蛇的坐标和移动距离，并根据键盘的方向去移动
        let x = this.snake.X
        let y = this.snake.Y
        let step = this.snake.step
        switch (this.direction) {
            case 'ArrowUp':
            case 'Up':
                y -= step
                break;
            case 'ArrowDown':
            case 'Down':
                y += step
                break;
            case 'ArrowLeft':
            case 'Left':
                x -= step
                break;
            case 'ArrowRight':
            case 'Right':
                x += step
                break;

        }
        // 检查蛇吃食物
        this.checkEat(x,y)
        // 捕获异常，并弹出异常信息，如撞到墙，蛇变死了，这个时候要停止移动，否则一直有alert
        try{
            this.snake.X = x 
            this.snake.Y = y 
        }catch (e){
            alert(e.message + 'Game Over !')


            this.isLive = false
        }
        
        this.isLive && setTimeout(this.run.bind(this),300 - (this.levelScore.level) * 30)
    }

    // 如果蛇移动的位置和食物一样，则代表吃到食物了，食物要改变位置、分数要增加、蛇要增加身体
    checkEat(x:number,y:number){
        if(x === this.food.X && y === this.food.Y){
            this.food.change()
            this.levelScore.addScore()
            this.snake.addBodies()
        }
    }
}


export default GameControl